package ynet

import (
	"bytes"
	"encoding/binary"
	"errors"
	"golang-zinx-demo/yanx/utils"
	"golang-zinx-demo/yanx/yiface"
)

// 封包、拆包的具体模块
type DataPack struct {
}

// 封包、拆包实例的一个初始化方法
func NewDataPack() *DataPack {
	return &DataPack{}
}

func (dp *DataPack) GetHeadLen() uint32 {
	// DataLen uint32（4字节）+ ID uint32（4字节）= 8 字节
	return 8
}

// 封包方法
func (dp *DataPack) Pack(msg yiface.IMessage) ([]byte, error) {
	// 创建一个存放bytes的缓冲
	dataBuff := bytes.NewBuffer([]byte{})
	// 将dataLen 写进dataBuf中
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetMsgLen()); err != nil {
		return nil, err
	}

	// 将MsgID 写进dataBuf中
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetMsgID()); err != nil {
		return nil, err
	}
	// 将data数据 写进dataBuf中
	if err := binary.Write(dataBuff, binary.LittleEndian, msg.GetMsgData()); err != nil {
		return nil, err
	}

	return dataBuff.Bytes(), nil
}

// 拆包方法 将包的head信息读出来，再根据head信息读取内容
func (dp *DataPack) UnPack(binaryData []byte) (yiface.IMessage, error) {
	// 创建一个输入二进制的ioReader
	dataBuff := bytes.NewReader(binaryData)

	// 只解压head信息，得到dataLen和MsgID
	msg := &Message{}
	// 读取dataLen
	if err := binary.Read(dataBuff, binary.LittleEndian, &msg.DataLen); err != nil {
		return nil, err
	}
	// 读取MsgID
	if err := binary.Read(dataBuff, binary.LittleEndian, &msg.Id); err != nil {
		return nil, err
	}

	// 判断dataLen是否已经超出我们允许的最大长度
	if utils.GlobalObject.MaxPackageSize > 0 &&
		msg.DataLen > utils.GlobalObject.MaxPackageSize {

		return nil, errors.New("too large message data recv！")
	}

	return msg, nil
}
